# """
# Person类就是一个模板，编程时仅供参考
# """
#
#
# class Person:
#     def __init__(self, _name, _age=30):
#         """
#         初始化函数，初始化未来的实例
#         :param name: 形参name 让实例拥有不同名字
#         """
#         self.name = _name
#         self.age = _age
#
#     def get_age(self):
#         """
#         封装 获取年纪方法
#         :return: 返回实例的年纪
#         """
#         return self.age
#
#     def set_age(self, age):
#         """
#         封装 设置年纪方法
#         :param age: 将要设置的年纪
#         """
#         self.age = age
#
#     def get_name(self):
#         """
#         封装 获取名字方法
#         :return: 返回实例的名字
#         """
#         return self.name
#
#     def set_name(self, name):
#         """
#         封装 设置名字方法
#         :param name: 将要设置的名字
#         """
#         self.name = name
#
#     def __str__(self):
#         """
#         对象转字符串函数
#         :return: 用一个字符串来表示对象
#         """
#         return f"名字：{self.get_name()}\t年纪：{self.get_age()}"
#
#
# # p1 = Person("马云")
# # print(p1.name, p1.age)
# # p1.set_name("马化腾")
# # p1.set_age(40)
# # print(p1.get_name(), p1.get_age())
#
#
# # p1 = Person("马云")
# # p2 = Person("马化腾", 35)
# # p3 = Person("李彦宏", 40)
# #
# # print(p1, p2, p3)
#
#
#
# # l0 = [Person("马云"), Person("马化腾", 20), Person("李彦宏", 40)]
#
# # l0.sort(key=lambda p: p.age, reverse=True)
# #
# # for p in l0:
# #     print(p)
#
#
# # l1 = [p for p in l0 if p.age < 25]
# # for e in l1:
# #     print(e)
#
#
#
#
# class PersonManage:
#     def __init__(self):
#         self.persons = []
#
#     def add_person(self, name, age):
#         p = Person(name, age)
#         self.persons.append(p)
#
#     def show_all_person_info(self):
#         for p in self.persons:
#             print(p)
#
#     def show_all_bellow_25(self):
#         for p in self.persons:
#             if p.age < 25:
#                 print(p)
#
#
#
# def main():
#     pm = PersonManage()
#     pm.add_person("马云1", 21)
#     pm.add_person("马云2", 22)
#     pm.add_person("马云3", 23)
#     pm.add_person("马云4", 24)
#
#     pm.show_all_person_info()
#     print("=======")
#     pm.show_all_bellow_25()
#
#
#
# main()
#
#
import math
import random
import time
import turtle

# import math
#
#
# class Circle:
#     def __init__(self, r):
#         self.r = r
#
#     def get_area(self):
#         return math.pi * self.r * self.r
#
#     def get_length(self):
#         return math.pi * 2 * self.r
#
#     def double_r(self):
#         self.r *= 2
#
#     def __str__(self):
#         return f"半径：{self.r}  周长：{self.get_length()}  面积：{self.get_area()}"
#
#
# c = Circle(10)
# print(c)
# c.double_r()
# print(c)


# 封装圆形类，
# 包含数据，圆心(x,y)，半径(r)
# 包含方法，面积与周长
#
#
# 封装管理类，管理10个 半径位于10-30之间的圆  位置在【0，0， 100， 100】
# 封装方法
#     找到面积最大的圆
#     找到距离最远的两个圆


# class Circle:
#     def __init__(self, x, y, r):
#         self.x = x
#         self.y = y
#         self.r = r
#
#     def get_area(self):
#         return math.pi * self.r * self.r
#
#     def get_length(self):
#         return 2 * math.pi * self.r
#
#     def __str__(self):
#         return f"X:{self.x} Y:{self.y} R:{self.r} Area:{self.get_area()} Length:{self.get_length()}"
#
#
#
# class CircleManage:
#     def __init__(self):
#         self.circles = []
#
#     def add_circle(self, x, y, r):
#         c = Circle(x, y, r)
#         self.circles.append(c)
#
#     def show_all_circles(self):
#         for c in self.circles:
#             print(c)
#
#     def get_max_area(self):
#         # return max(self.circles, key=lambda c: c.get_area())
#
#         max_circles = []
#         max_area = 0
#
#         for c in self.circles:
#             if max_area < c.get_area():
#                 max_circles.clear()
#                 max_area = c.get_area()
#                 max_circles.append(c)
#
#             elif max_area == c.get_area():
#                 max_circles.append(c)
#
#         return max_circles
#
#     def get_max_length(self):
#         max_length = 0
#         circles = []
#         for i in range(len(self.circles) - 1):
#             for j in range(i+1, len(self.circles)):
#                 dis = math.sqrt((self.circles[i].x - self.circles[j].x) ** 2 + (self.circles[i].y - self.circles[j].y) ** 2)
#                 if max_length < dis:
#                     max_length = dis
#                     circles.clear()
#                     circles.append(self.circles[i])
#                     circles.append(self.circles[j])
#         return circles
#
#
#
#
#
#
# def main():
#     cm = CircleManage()
#     cm.add_circle(1000, 1000, 30)
#     for i in range(10):
#         cm.add_circle(random.randint(0,100), random.randint(0,100), random.randint(10,30))
#
#     cm.show_all_circles()
#     print("========")
#     max_circles = cm.get_max_area()
#     for c in max_circles:
#         print(f"面积最大的圆:{c}")
#     print("========")
#
#     for c in cm.get_max_length():
#         print(f"最大距离的圆{c}")


# main()


# 三、创建Rectangle类，初始化属性width、height；
# 在Rectangle类中添加两个方法计算矩形的周长和面积；
# 在Rectangle类中添加方法输出矩形的周长和面积
# 生成10个矩形 width,height都位于 5-10之间  求周长与面积之和最大的一个矩形

# class Rect:
#     def __init__(self, width, height):
#         self.width = width
#         self.height = height
#
#     def get_area(self):
#         return self.width * self.height
#
#     def get_length(self):
#         return 2 * (self.width + self.height)
#
#     def info(self):
#         return f"矩形信息  Length：{self.get_length()}  Width:{self.width} Area:{self.get_area()} Length: {self.get_length()}"

# def __str__(self):
#     return self.info()


# r = Rect(10, 200)
# print(r.info())
# # print(r)

# def main():
#     l = []
#     for i in range(10):
#         r = Rect(random.randint(5, 10), random.randint(5, 10))
#         l.append(r)
#
#     max_r = max(l, key=lambda r: r.get_area() + r.get_length())
#
#     print(max_r.info())
#
# main()


# 四、使用面向对象封装一个栈（百度一个 栈 ：后进先出）
# 提供插入数据与删除数据的方法。插入的数据放在最后，删除的数据就是最后一个插入	的数据，提供方法返回栈中元素的个数


# class Stack:
#     def __init__(self, count=5):
#         self.datas = []
#         self.count = count
#
#     def is_full(self):
#         return len(self.datas) == self.count
#
#     def is_empty(self):
#         return len(self.datas) == 0
#
#     def put(self, e):
#         if self.is_full():
#             print(f"已经满栈 不能继续放入元素")
#         else:
#             self.datas.append(e)
#
#     def get(self):
#         if self.is_empty():
#             print(f"空栈 不能取出元素")
#         else:
#             return self.datas.pop()
#
#
#
#
#
# stack = Stack()
# print(stack.is_full(), stack.is_empty())
# stack.put(10)
# stack.put(20)
# print(stack.is_full(), stack.is_empty())
# e = stack.get()
# print(e)
# e = stack.get()
# print(e)
# e = stack.get()
# print(e)
# stack.put(10)
# stack.put(20)
# stack.put(30)
# stack.put(40)
# stack.put(50)
# stack.put(60)
# print(stack.is_full(), stack.is_empty())
# e = stack.get()
# print(e)
# print(stack.is_full(), stack.is_empty())


# 五、新建学生类（学号，姓名，年纪）
#  	随机生成10个学生放入列表(年纪随机即可)，按学生的年纪对列表中的学生排序

# class Student:
#     def __init__(self, sid, name, age):
#         self.sid = sid
#         self.name = name
#         self.age = age
#
#     def __str__(self):
#         return f"学号:{self.sid}  姓名:{self.name}  年纪：{self.age}"
#
#
# def main():
#     l = []
#     for i in range(10):
#         s = Student(101 + i, f"张{i}", random.randint(10, 30))
#         l.append(s)
#
#     # l.sort(key=lambda s : s.age)
#
#     # for i in range(len(l) - 1):
#     #     for j in range(i+1, len(l)):
#     #         if l[i].age > l[j].age:
#     #             temp = l[i]
#     #             l[i]=l[j]
#     #             l[j]=temp
#
#     for i in range(len(l) - 1):
#         max_index = i
#         for j in range(i + 1, len(l)):
#             if l[j].age < l[max_index].age:
#                 max_index = j
#
#         if max_index != i:
#             temp = l[max_index]
#             l[max_index] = l[i]
#             l[i] = temp
#
#     for s in l:
#         print(s)
#
#
# main()


# class Car:
#     def __init__(self, color, speed):
#         self.color = color
#         self.speed = speed
#
#     def __str__(self):
#         return f"颜色 {self.color}  速度 {self.speed}"
#
#
# c1 = Car("红色", 100)
# c2 = Car("白色", 120)
# c3 = Car("黑色", 90)
#
#
# class Person:
#     def __init__(self, name, car):
#         self.name = name
#         self.car = car
#
#     def __str__(self):
#         return f"名字 {self.name} 车辆信息 {self.car}"
#
#
# p1 = Person("小张", c1)
# # print(p1)
#
# p2 = Person("小杨", c2)
# # print(p2)
#
# p3 = Person("小李", c3)
# # print(p3)
#
# l = [p1, p2, p3]
#
# for p in l:
#     print(p)


# 一、创建一个名为 Person 的类，拥有 name 和 age 两个属性。实例化几个 Person 对象，并打印它们的属性。
# class Person(object):
#     def __init__(self, name, age):
#         self.name = name
#         self.age = age
#
#     def get_name(self):
#         return self.name
#
#     def get_age(self):
#         return self.age
#
# p1 = Person("张三", 20)
# p2 = Person("李四", 30)
#
# # print(p1.name, p1.age, p2.name, p2.age)
# print(p1.get_name(), p1.get_age(), p2.get_name(), p2.get_age())


# 二、创建一个名为 BankAccount 的类，拥有 balance 属性和 deposit()、withdraw() 两个方法。实例化一个 BankAccount 对象，然后进行一些存款和取款操作。

# class BankAccount(object):
#     def __init__(self):
#         self.balance = 0
#
#     def deposit(self, money):
#         self.balance += money
#         print(f"余额：{self.balance}")
#
#     def withdraw(self, money):
#         if self.balance >= money:
#             self.balance -= money
#             print(f"余额：{self.balance}")
#         else:
#             print(f"余额不足")
#
# ba = BankAccount()
# ba.withdraw(100)
#
# ba.deposit(10000)
#
# ba.withdraw(1000)
# ba.withdraw(5000)
# ba.withdraw(3000)


# 三、创建一个名为 Car 的类，拥有 brand 和 color 两个属性，以及 start() 和 stop() 两个方法。
# 实例化一个 Car 对象，并调用 start() 和 stop() 方法。

# class Car:
#     def __init__(self, brand, color):
#         self.brand = brand
#         self.color = color
#         self.enabled = False
#         self.speed = 0
#
#     def start(self):
#         self.enabled = True
#
#     def speed_up(self):
#         if self.is_runing():
#             self.speed += 20
#             if self.speed >= 120:
#                 print(f"已经超速，请注意")
#         else:
#             print(f"请先启动")
#
#     def speed_down(self):
#         if self.speed > 0:
#             self.speed -= 20
#         if self.speed < 0:
#             self.speed = 0
#
#     def stop(self):
#         self.enabled = False
#
#     def is_runing(self):
#         return self.enabled
#
#     def __str__(self):
#         return f"品牌{self.brand}  颜色{self.color}  状态:{f'正在运行 速度：{self.speed}' if self.is_runing() else '已经熄火'}"
#
#
# c1 = Car("保时捷", "红色")
# c1.start()
# print(c1)
# c2 = Car("米时捷", "白色")
# c2.start()
# c2.speed_up()
# c2.speed_up()
# c2.speed_up()
# print(c2)


# from datetime import date, timedelta
# # 四、创建一个名为 Employee 的类，拥有 name、salary 和 hire_date 三个属性。实现一个计算员工服务年限的方法，并打印出员工的名字、薪水和服务年限。
# class Employee:
#     def __init__(self, name, salary, hire_date):
#         self.name = name
#         self.salary = salary
#         self.hire_date = hire_date
#
#     def serve_time(self):
#         now = date.today()
#         red = (now - self.hire_date)
#         return red.days
#
# e1 = Employee("小张", 10000, date(year=2023, month=6, day=1))
# print(e1.serve_time())


# from datetime import datetime
# now = datetime.now()
# print(now, now.strftime("%Y年%m月%d日"))
#
# now_str = "2020/01/01"
# r = datetime.strptime(now_str, "%Y/%m/%d")
# print(r)


# 五、创建一个名为 Student 的类，拥有 name、id 和 scores 三个属性。scores 是一个字典，包含多个科目的成绩。为 Student 实现一个名为 average_score() 的方法，计算该学生的平均分数

# class Student:
#     def __init__(self, sid, name, scores):
#         self.sid = sid
#         self.name = name
#         self.scores = scores
#
#     def average_score(self):
#         total = 0
#         for v in self.scores.values():
#             total += v
#
#         return f"学号{self.sid}  姓名{self.name}    平均分{total / len(self.scores)}"
#
#     def max_scores(self):
#         max_value = 0
#         max_k = None
#         for k, v in self.scores.items():
#             if max_value < v:
#                 max_value = v
#                 max_k = k
#
#         print(max_k, max_value)
#
# s1 = Student(101, "小张", {"python": 100, "js": 50})
#
# s1.max_scores()
# print(s1.average_score())

# 六、编写汽车类（颜色，速度）
# 编写人类（名字，汽车实例）
# 编写列表 放入三个人， 遍历列表依次打印每个人的信息（包含汽车）
# class Car:
#     def __init__(self, color, speed):
#         self.color = color
#         self.speed = speed
#
#     def __str__(self):
#         return f"颜色{self.color} 速度{self.speed}"
#
# class Person:
#     def __init__(self, name, car):
#         self.name = name
#         self.car = car
#
#     def __str__(self):
#         return f"人员信息 {self.name}  车辆信息 {self.car}"
#
# c1 = Car("红色", 100)
# c2 = Car("白色", 120)
#
# p1 = Person("小张", c1)
# p2 = Person("小王", c2)
#
# l = [p1, p2]
# for p in l:
#     print(p)

# 七、编写学生类，课程类，成绩类 以及对应的管理类完成学生管理系统实现
# student  studentmanage   curse cursemanage  score scoremanage  systemmange


# 八、使用turtle模块结合类封装一下功能，
# 绘制圆形，绘制矩形，绘制三角形

# class Draw:
#     def __init__(self, width=3, bgcolor="grey", pencolor="pink"):
#         turtle.width(width)
#         turtle.bgcolor(bgcolor)
#         turtle.pencolor(pencolor)
#
#     def draw_rect(self, star_x, start_y, width, height):
#         turtle.setheading(0)
#         turtle.up()
#         turtle.goto(star_x, start_y)
#         turtle.down()
#         turtle.forward(width)
#         turtle.left(90)
#         turtle.forward(height)
#         turtle.left(90)
#         turtle.forward(width)
#         turtle.left(90)
#         turtle.forward(height)
#
#     def run(self):
#         turtle.mainloop()
#
#
# draw = Draw()
# draw.draw_rect(100, 100, 200, 200)
# draw.run()

# 九、编写装饰器两个案例（统计时间开销，添加权限校验），添加详细注释


# def time_cost(f):
#     def calc():
#         start = time.time()
#         f()
#         print(f"{f.__name__}时间消耗: {time.time()-start}")
#     return calc
#
# @time_cost
# def method1():
#     time.sleep(5)
#
# @time_cost
# def method2():
#     time.sleep(10)
# # method1 = time_cost(method1)
# method1()
#
# method2()


# 十、使用面向对象封装一个队列与栈


# class Queue:
#     def __init__(self, count=5):
#         self.datas = []
#         self.count = count
#
#     def is_empty(self):
#         return len(self.datas) == 0
#
#     def is_full(self):
#         return len(self.datas) == self.count
#
#     def put(self, e):
#         if self.is_full():
#             print(f"满队 不能放入元素")
#         else:
#             self.datas.append(e)
#
#     def get(self):
#         if self.is_empty():
#             print(f"空对 不能取出元素")
#         else:
#             return self.datas.pop(0)
#
#
# q = Queue()
# print(q.is_empty(), q.is_full())
# q.put(1)
# q.put(2)
# q.put(3)
# q.put(4)
# q.put(5)
# q.put(6)
# print( q.get())
# print( q.get())
# print( q.get())
# print( q.get())
# print( q.get())
# print( q.get())
#
# print(q.is_empty(), q.is_full())


# 提供是否满、是否空、数量、入队出队，入栈出站对应方法


# 十一、编写角色类，拥有血量【3000,5000】和攻击力【100,300】
#  随机10个角色（血量，攻击力随机）放入列表
#      列表中的角色依次攻击下一个（最后一个攻击第一个）
#  角色死亡后移除列表，输出最后存货角色信息

# class Hero:
#     def __init__(self, name, hp, ack):
#         self.name = name
#         self.hp = hp
#         self.ack = ack
#
#     def __str__(self):
#         return f"名字 {self.name}  血量{self.hp}  攻击力{self.ack}"
#
# heros = [Hero(f"角色{i+1}", random.randint(3000, 5000), random.randint(100, 300)) for i in range(10)]
#
# for h in heros:
#     print(h)
#
# while len(heros) > 1:
#     print(f"开始新一轮攻击")
#     for i in range(len(heros) - 1):
#         if heros[i].hp >0:
#             heros[i + 1].hp -= heros[i].ack
#     if heros[-1].hp > 0:
#         heros[0].hp -= heros[-1].ack
#
#     print(f"攻击结束")
#
#     for h in heros:
#         print(h)
#
#     print(f"清理死亡角色")
#     for i in range(len(heros)-1, -1, -1):
#         if heros[i].hp <= 0:
#             print(f"{heros[i].name} 死亡")
#             heros.remove(heros[i])
#
#     print(f"剩余角色{len(heros)}")
#     for h in heros:
#         print(h)


# 十二、饲养员类
# 数据：名字
# 方法：喂养(动物，草)
#               行走()
# 动物类
# 数据：名字
# 方法：吃
#   行走
# 食物类
# 数据：名字
# 实现饲养员给动物喂食物。
#


# 十三、Z:\share\python2405\第一阶段\作业\90.GUI 绘图软件.exe


# import tkinter
# from tkinter import colorchooser
# from tkinter import messagebox
#
# root = tkinter.Tk()
#
# # label = tkinter.Label(root, text="我是一个文本")
# # label.pack()
# #
# # button = tkinter.Button(root, text="点击", command=lambda: print("点击了"))
# # button.pack()
#
# main_menu = tkinter.Menu(root)
#
# # 构建菜单1
# menu1 = tkinter.Menu(main_menu, tearoff=False)
# menu1.add_command(label="矩形", command=lambda: print("点击了矩形"))
# menu1.add_command(label="圆形", command=lambda: print("点击了圆形"))
# menu1.add_command(label="直线", command=lambda: print("点击了直线"))
#
# # 将菜单1 添加到主菜单
# main_menu.add_cascade(menu=menu1, label="图形")
#
# menu2 = tkinter.Menu(main_menu, tearoff=False)
# menu2.add_command(label="红色", command=lambda: print("点击了红色"))
#
# def select_color():
#     r = colorchooser.askcolor()
#     print(r)
#
# menu2.add_command(label="自定义", command=select_color)
#
# def exit():
#     r = messagebox.askyesno(title="退出", message="是否退出程序")
#     if r:
#         root.destroy()
# menu2.add_command(label="退出", command=exit)
#
#
# main_menu.add_cascade(menu=menu2, label="颜色")
#
# # 给root窗体添加菜单
# root.config(menu=main_menu)
#
# canvas = tkinter.Canvas(root, width=800, height=600)
# canvas.create_line(0, 0, 100, 100)
# canvas.create_oval(100, 100, 200, 600)
# # 绘制图形三
# shape_id = canvas.create_rectangle(300, 300, 400, 500)
# print(shape_id)
# # canvas.delete(shape_id)
# # canvas.delete(1)
# # canvas.delete("all")
# # 更新一个图形三
# canvas.coords(shape_id, 120, 300, 450, 100)
#
# # 给画布绑定事件
# canvas.bind("<Button-1>", func=lambda e: print(f"点击了左键{e.x} {e.y}"))
# canvas.bind("<Button-2>", func=lambda e: print(f"点击了中键{e.x} {e.y}"))
# canvas.bind("<Button-3>", func=lambda e: print(f"点击了右键{e.x} {e.y}"))
#
# # canvas.bind("<Motion>", func=lambda e:print(f"鼠标移动了 {e.x} {e.y}"))
#
# canvas.bind("<ButtonRelease-1>", lambda e:print(f"鼠标左键抬起 {e.x} {e.y}"))
#
# canvas.pack()
#
#
#
# root.mainloop()














